package org.file5.controller.admin;

import java.util.List;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.file5.domain.Article;
import org.file5.domain.BaseEntity;
import org.file5.domain.Category;
import org.file5.domain.Entity2Entity;
import org.file5.domain.Entity2Entity.Relation;
import org.file5.domain.Person;
import org.file5.search.SearchUtility;
import org.file5.service.CategoryService;
import org.file5.service.ServiceFascade;
import org.file5.util.DataBean;
import org.file5.util.LoremIpsum;
import org.file5.util.UUIDUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.googlecode.objectify.Key;

@Controller
@RequestMapping("/admin/article")
public class AdminArticleController {
	private final Logger logger = Logger.getLogger(this.getClass());

	@Autowired
	private ServiceFascade sf;
	@Autowired
	private UserService googleUserService;

	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public String articleList(@RequestParam(value = "guid", required = false) String categoryUid,
			@RequestParam(value = "pageNo", required = false) Integer pageNo,
			@RequestParam(value = "pageSize", required = false) Integer pageSize, Model model) {

		if (pageNo == null || pageNo < 0) {
			pageNo = 0;
		}
		if (pageSize == null || pageSize < 1) {
			pageSize = DataBean.PAGE_SIZE_ADMIN;
		}
		Category g = sf.getCategoryService().find(categoryUid);

		DataBean<Article> dataBean = sf.getArticleService().getArticles(pageNo * pageSize, pageSize, g,null);

		model.addAttribute("pageNo", pageNo);
		model.addAttribute("pageSize", pageSize);
		if (dataBean != null && !dataBean.isEmpty()) {
			model.addAttribute("articles", dataBean.getData());
			model.addAttribute("totalItems", dataBean.getCount());
		}
		if (g == null) {
			g = sf.getCategoryService().findTopSiteArticleCategory();
		} else {
			model.addAttribute("currentCategory", g);
			model.addAttribute("primaryCategoryTrail", g.getPrimaryCategoryTrail());
		}
		model.addAttribute("childCategories", g.getChildCategories());

		return "admin/article/articles";
	}

	@RequestMapping("/publish")
	public String articlePublish(@RequestParam(value = "uid") String uid, Model model) {
		Article article = sf.getArticleService().updateStatus(uid, BaseEntity.STATUS.ONLINE);
		String categoryUid = article.getPrimaryCategoryKey() == null ? "" : article.getPrimaryCategoryKey().getName();
		return "redirect:/admin/article/list.asp?guid=" + categoryUid;
	}

	@RequestMapping("/unpublish")
	public String articleUnpublish(@RequestParam(value = "uid") String uid, Model model) {
		Article article = sf.getArticleService().updateStatus(uid, BaseEntity.STATUS.OFFLINE);
		String categoryUid = article.getPrimaryCategoryKey() == null ? "" : article.getPrimaryCategoryKey().getName();
		return "redirect:/admin/article/list.asp?guid=" + categoryUid;
	}

	@RequestMapping(value = "/add", method = RequestMethod.GET)
	public String articleAdd(@RequestParam(value = "pguid", required = false) String primaryCategoryUid,
			HttpServletRequest request) {

		Article article = newDummyArticle(request, primaryCategoryUid);
		return "redirect:/admin/article/edit.htm?uid=" + article.getUid();

	}

	@RequestMapping("/delete")
	public String articleDelete(@RequestParam(value = "uid") String articleUid, Model model) {
		Article article = sf.getBaseService().find(Article.class, articleUid);
		String categoryUid = article.getPrimaryCategoryKey() == null ? "" : article.getPrimaryCategoryKey().getName();
		if (article != null) {
			SearchUtility.deleteEntityIndex(article);
			sf.getArticleService().delete(articleUid);
		}

		return "redirect:/admin/article/list.asp?guid=" + categoryUid;
	}

	@RequestMapping("/list/delete")
	public String articlesDelete(@RequestParam(value = "uid", required = false) String[] articleUids, Model model) {
		if (articleUids != null && articleUids.length > 0) {
			for (String uid : articleUids) {
				Article p = sf.getBaseService().find(Article.class, uid);
				if (p != null) {
					SearchUtility.deleteEntityIndex(p);
					sf.getArticleService().delete(uid);
				}

			}
		}
		return "redirect:/admin/article/list.asp";
	}

	@RequestMapping(value = "/setprimarycategory", method = RequestMethod.GET)
	public String articlePrimaryCategorySet(@RequestParam(value = "pguid", required = false) String pguid,
			@RequestParam(value = "uid") String uid, @RequestParam(value = "set", required = false) String set,
			Model model, HttpServletRequest request) {
		Article article = sf.getBaseService().find(Article.class, uid);
		if (article != null) {
			model.addAttribute("article", article);
			List<Category> articleCategories = sf.getArticleService().getArticleCategories(article);
			model.addAttribute("articleCategories", articleCategories);
			if (article.getPrimaryCategoryKey() != null) {

				List<Category> primaryCategoryTrail = sf.getCategoryService().getPrimaryCategoryTrail(
						article.getPrimaryCategoryKey());
				model.addAttribute("articlePrimaryCategoryTrail", primaryCategoryTrail);

			}

			Category g = null;
			if (pguid != null && !"".equals(pguid.trim())) {
				g = sf.getCategoryService().find(pguid);
			}
			if (g == null) {
				g = sf.getCategoryService().findTopSiteArticleCategory();
			}
			if (set != null && "Y".equals(set)) {
				sf.getArticleService().setArticlePrimaryCategory(article, g);
				return "redirect:/admin/article/edit.htm?uid=" + uid;
			}
			model.addAttribute("currentCategory", g);
			model.addAttribute("primaryCategoryTrail", g.getPrimaryCategoryTrail());
			model.addAttribute("childCategories", g.getChildCategories());

			return "admin/article/articlecategoryedit";
		} else {
			return "redirect:/admin/article/list.htm";
		}
	}

	@RequestMapping(value = "/category/delete", method = RequestMethod.GET)
	public String categoryDelete(@RequestParam(value = "uid", required = false) String categoryUid,
			HttpServletRequest request) {
		if (categoryUid != null && !CategoryService.TOP_SITE_ARTICLE_CATEGORY_UID.equals(categoryUid)) {
			Category g = sf.getBaseService().find(Category.class, categoryUid);
			if (g != null) {
				sf.getBaseService().remove(g);
			}
		}
		return "redirect:/admin/article/categories.htm";

	}

	@RequestMapping(value = "/category/add", method = RequestMethod.GET)
	public String categoryAdd(@RequestParam(value = "puid", required = false) String parentCategoryUid,
			@RequestParam(value = "uid", required = false) String categoryUid, HttpServletRequest request) {
		if (categoryUid == null || categoryUid != null
				&& !categoryUid.trim().equals(CategoryService.TOP_GENERAL_PRODUCT_CATEGORY_UID)
				&& !categoryUid.trim().equals(CategoryService.TOP_SITE_PRODUCT_CATEGORY_UID)
				&& !categoryUid.trim().equals(CategoryService.TOP_SITE_ARTICLE_CATEGORY_UID)) {
			Category pg = sf.getCategoryService().find(parentCategoryUid);
			if (pg == null) {
				pg = sf.getCategoryService().findTopSiteArticleCategory();
			}
			Category g = newDummyArticleCategory(pg.getUid(), categoryUid);
			return "redirect:/admin/article/category/edit.htm?uid=" + g.getUid();
		} else if (categoryUid != null && categoryUid.trim().equals(CategoryService.TOP_GENERAL_PRODUCT_CATEGORY_UID)) {
			Category pg = sf.getCategoryService().findTopGeneralProductCategory();
		} else if (categoryUid != null && categoryUid.trim().equals(CategoryService.TOP_SITE_PRODUCT_CATEGORY_UID)) {
			Category pg = sf.getCategoryService().findTopSiteProductCategory();

		}

		return "redirect:/admin/article/categories.htm";

	}

	@RequestMapping(value = "/categories", method = RequestMethod.GET)
	public String categoryList(@RequestParam(value = "puid", required = false) String parentCategoryUid, Model model,
			HttpServletRequest request) {
		Category g = null;
		if (parentCategoryUid != null && !"".equals(parentCategoryUid)) {
			g = sf.getCategoryService().find(parentCategoryUid);
		}
		if (g == null) {
			g = sf.getCategoryService().findTopSiteArticleCategory();
		}

		model.addAttribute("currentCategory", g);
		model.addAttribute("primaryCategoryTrail", g.getPrimaryCategoryTrail());
		model.addAttribute("childCategories", g.getChildCategories());

		return "admin/article/categories";

	}

	@RequestMapping(value = "/category/setprimaryparentcategory", method = RequestMethod.GET)
	public String categoryPrimaryParentCategorySet(@RequestParam(value = "pguid", required = false) String pguid,
			@RequestParam(value = "uid") String uid, @RequestParam(value = "set", required = false) String set,
			Model model, HttpServletRequest request) {
		Category category = sf.getBaseService().find(Category.class, uid);
		if (category != null) {
			model.addAttribute("category", category);
			if (category.getPrimaryParentKey() != null) {

				List<Category> parentCategoryTrail = sf.getCategoryService().getPrimaryCategoryTrail(
						category.getPrimaryParentKey());
				model.addAttribute("parentCategoryTrail", parentCategoryTrail);

			}

			Category g = null;
			if (pguid != null && !"".equals(pguid.trim())) {
				g = sf.getCategoryService().find(pguid);
			}
			if (g == null) {
				g = sf.getCategoryService().findTopSiteArticleCategory();
			} else {
				model.addAttribute("childCategories", g.getChildCategories());
			}
			if (set != null && "Y".equals(set)) {
				sf.getCategoryService().setPrimaryParent(category, g);
				return "redirect:/admin/article/category/setprimaryparentcategory.htm?uid=" + uid;
			}
			model.addAttribute("currentCategory", g);
			model.addAttribute("primaryCategoryTrail", g.getPrimaryCategoryTrail());

			return "admin/article/categoryparentedit";
		} else {
			return "redirect:/admin/article/categories.htm";
		}
	}

	private Category newDummyArticleCategory(String parentCategoryUid, String categoryUid) {
		Category g = new Category();
		if (categoryUid != null) {
			g.setUid(categoryUid);
		} else {
			g.setUid(UUIDUtil.getRandomUUID());
		}

		// g.setType(type);
		g.setName("新建分类");
		Category pg = sf.getBaseService().find(Category.class, parentCategoryUid);
		if (pg != null) {
			g.setPrimaryParentKey(new Key<Category>(Category.class, parentCategoryUid));
		}
		sf.getBaseService().addUpdate(g);
		return g;

	}

	// =========================================================================
	// =========================================================================
	// =========================================================================
	// =========================================================================

	private Article newDummyArticle(HttpServletRequest request, String primaryCategoryUid) {

		User googleUser = googleUserService.getCurrentUser();
		String authorUid = sf.getPersonService().getPersonUid(googleUser);

		String articleUid = UUIDUtil.getRandomUUID();
		Article article = new Article();
		article.setUid(articleUid);
		Random r = new Random();
		article.setName("新建博文" + r.nextInt());

		article.setLongDesc(LoremIpsum.LOREM_IPSUM
				+ " 没有博客，建立博客，<a title='开通博客，博客网站，免费建站' alt='开通博客，博客网站，免费建站' target='_blank' href='http://fatcatdata.appspot.com/help.htm'>开博帮助</a>");

		article.setAuthorKey(new Key<Person>(Person.class, authorUid));
		sf.getBaseService().addUpdate(article);

		if (primaryCategoryUid != null) {
			Category pg = sf.getBaseService().find(Category.class, primaryCategoryUid);
			if (pg != null) {
				article.setPrimaryCategoryKey(new Key<Category>(Category.class, primaryCategoryUid));
				sf.getBaseService().addUpdate(article);


				List<Category> trail = sf.getCategoryService().getPrimaryCategoryTrail(
						new Key<Category>(Category.class, primaryCategoryUid));

				sf.getArticleService().addArticle2Categories(article, trail);
			}
		}
		return article;
	}

	// =========================================================================
	// =========================================================================
	// =========================================================================
	// =========================================================================

}
